import { RepoLink, Link } from '@brillout/docpress'
import PreRenderDynamicRoutes from './PreRenderDynamicRoutes.mdx'


## What is pre-rendering?

Pre-rendering means to render the HTML of pages at build-time (when running `$ vite build`).

Without pre-rendering, the HTML of a page is rendered at request-time (when the user goes to that page).

If you pre-render all of your pages, then you no longer need a production server: your app will consist only of static assets (HTML, JS, CSS, images, ...)
that you can deploy to so-called "static hosts" such as <Link href="/github-pages" text="GitHub Pages" />, [Cloudflare Pages](/cloudflare-pages), or [Netlify](/netlify).

If you don't pre-render, then you need a production server in order to be able to dynamically render the HTML of your pages at request-time. (A Node.js production server, or a Node.js-like production environment such as <Link href="/cloudflare-workers" text="Cloudflare Workers" /> or <Link href="/vercel" text="Vercel" />.)

> Tools that pre-render pages are also known as "SSG" (Static-Site Generators).


## Should I pre-render?

In a nutshell: pre-render your pages whenever you can.

Because pre-rendering removes the need for a production server and therefore makes deployment easy. It's also significantly more performant as the HTML isn't re-generated on every HTTP request.

But pre-rendering cannot be used for every kind of website.

Pre-rendering cannot be used for websites with content that changes very frequently. For example, a social site such as [Hacker News](https://news.ycombinator.com/) or [Reddit](https://www.reddit.com/): new content is created every time a user shares a link or writes a comment. Pre-rendering cannot be run again and again every other (milli)second whenever there is new content (Reddit has millions of pages which obviously cannot all be re-rendered every other millisecond). (In theory, it's possible to re-render only the subset of pages that are affected by new content, but it isn't practical and we recommend against this practice.)

Pre-rendering can be used for websites with content that changes only occasionally. For example, the content of `https://vike.dev` changes only when a maintainer updates the documentation: all pages of `https://vike.dev` can then be pre-rendered again. Thanks to pre-rendering, `https://vike.dev` is deployed to the static host <Link href="/github-pages" text="GitHub Pages" />, which is a lot easier (and more performant) than using a production server.


## How to pre-render

To opt into pre-rendering:

```js
// vite.config.js

import vike from 'vike/plugin'

export default {
  plugins: [
    vike({ prerender: true })
  ]
}
```

List of options: <Link href="/prerender" />.

Your pages' HTML will be rendered when you run `$ vite build` and the generated HTML files are available at `dist/client/`.

For a page with a parameterized route (e.g. `/movie/@movieId`), you have to use the <Link href="/onBeforePrerenderStart">`onBeforePrerenderStart()` hook</Link> in order to provide the list of URLs that are to be pre-rendered. The `onBeforePrerenderStart()` hook can also be used to accelerate the pre-rendering process.

<PreRenderDynamicRoutes />

By default, all pages are pre-rendered. To pre-render only some pages, use the <Link href="/prerender#partial" text={<><code>partial</code> option</>} /> with <Link href="/prerender#toggle" text={<code>prerender: false</code>} />.

If you pre-render all your pages, then you can use Vite's CLI instead of a server (`$ vite dev` and `$ vite preview`). See linked examples below.

You can programmatically invoke the pre-rendering process, see <Link href="/prerender-programmatic" />.

React Example:
 - <RepoLink path='/examples/react-full/vite.config.ts' /> (see setting <code>prerender</code> option to `true`)
 - <RepoLink path='/examples/react-full/pages/hello/+onBeforePrerenderStart.ts' />
 - <RepoLink path='/examples/react-full/pages/star-wars/index/+onBeforePrerenderStart.ts' />
 - <RepoLink path='/examples/react-full/package.json' /> (see Vite CLI usage)

Vue Example:
 - <RepoLink path='/examples/vue-full/vite.config.ts' /> (see setting <code>prerender</code> option to `true`)
 - <RepoLink path='/examples/vue-full/pages/hello/+onBeforePrerenderStart.ts' />
 - <RepoLink path='/examples/vue-full/pages/star-wars/index/+onBeforePrerenderStart.ts' />
 - <RepoLink path='/examples/vue-full/package.json' /> (see Vite CLI usage)


## SSG vs SSR

The only difference between SSG and SSR is *when* the HTML is rendered:
- SSG: the HTML of pages is rendered at build-time (when calling `$ vite build`)
- SSR: the HTML of pages is rendered at request-time (when the user goes to that page)

> The client-side code of pages is loaded and executed in the user's browser and is therefore always executed at request-time.


## See also

Related docs:

- <Link href="/data-fetching#pre-rendering-ssg" doNotInferSectionTitle />
- <Link href="/static-hosts" />
- <Link href="/ssr" />

Pre-rendering options:

- <Link href="/prerender" />
- <Link href="/prerender-programmatic" />
- <Link href="/onBeforePrerenderStart" />
- <Link href="/onPrerenderStart" />
- <Link href="/command-prerender" />
